<?php

/**
 * This is the model class for table "users".
 *
 * The followings are the available columns in table 'users':
 * @property integer $user_id
 * @property string $username
 * @property string $email
 * @property string $password
 * @property string $salt
 * @property string $display_name
 * @property string $activation_key
 * @property string $type
 * @property integer $status
 * @property integer $joined
 * @property string $first_name
 * @property string $last_name
 * @property string $gender
 * @property string $social_provider
 * @property string $social_uid
 * @property string $access_token
 * @property string $bio
 * @property integer $last_login_time
 * @property string $last_login_ip
 * @property string $country
 * @property string $state
 * @property string $city
 * @property string $address
 * @property string $phone
 * @property string $telephone
 * @property string $mobile
 * @property string $postcode
 * @property integer $featured
 * @property string $avatar
 * @property string $webpage
 * @property string $timezone
 * @property string $language
 *
 * The followings are the available model relations:
 * @property Posts[] $posts
 */
class User extends CActiveRecord {

  /**
   * hold the password after find
   * @var string
   */
  public $initialPassword;

  const MAX_LOGIN_ATTEMPTS = 3;

  public $username;
  public $password;
  public $email;
  public $rememberMe;
  public $verifyCode;
  private $_identity;
  private $_user = null;

  /**
   * password required when change or create new
   * @var string
   */
  public $repassword;

  const STATUS_WAITING_ACTIVE = 0;
  const STATUS_ACTIVE = 1;
  const STATUS_SUSPENDED = 2;
  const GENDER_FEMALE = 'female';
  const GENDER_MALE = 'male';

  /**
   * define user type
   */
  const TYPE_SUPER_ADMIN = 'supperAdmin';
  const TYPE_ADMIN = 'admin';
  const TYPE_MEMBER = 'member';

  /**
   * Returns the static model of the specified AR class.
   * @param string $className active record class name.
   * @return User the static model class
   */
  public static function model($className = __CLASS__) {
    return parent::model($className);
  }

  /**
   * @return string the associated database table name
   */
  public function tableName() {
    return '{{users}}';
  }

  /**
   * @return array validation rules for model attributes.
   */
  public function rules() {
    // NOTE: you should only define rules for those attributes that
    // will receive user inputs.
    return array(
        // array('txtEmailAddress', 'required'),
        array('email', 'required'),
        array('password, repassword', 'required', 'on' => 'insert'),
        array('username, email', 'unique'),
        array('email', 'email'),
        array('gender', 'in', 'range' => array(self::GENDER_FEMALE, self::GENDER_MALE)),
        array('user_id, status, joined, last_login_time, featured', 'numerical', 'integerOnly' => true),
        array('email, password, salt, display_name, activation_key', 'length', 'max' => 128),
        array('type, first_name, last_name, social_provider, last_login_ip, username', 'length', 'max' => 25),
        array('gender', 'length', 'max' => 6),
        array('social_uid, access_token, address, avatar, webpage', 'length', 'max' => 255),
        array('country, state, city, telephone, mobile, timezone', 'length', 'max' => 45),
        array('phone, postcode', 'length', 'max' => 15),
        array('language', 'length', 'max' => 10),
        array('bio', 'safe'),
        // The following rule is used by search().
        // Please remove those attributes that should not be searched.
        array('user_id, email, password, salt, display_name, type, status, joined, first_name, last_name, gender, social_provider, social_uid, access_token, bio, country, state, city, address, phone, telephone, mobile, postcode, webpage, language', 'safe', 'on' => 'search'),
    );
  }

  /**
   * @return array relational rules.
   */
  public function relations() {
    // NOTE: you may need to adjust the relation name and the related
    // class name for the relations automatically generated below.
    return array(
        'profile' => array(self::HAS_ONE, 'Profile', 'user_id'),
        'userPhoto' => array(self::HAS_ONE, 'UserPhoto', 'user_id','condition'=>'profile.user_id = userPhoto.user_id')

    );
  }

  /**
   * @return array customized attribute labels (name=>label)
   */
  public function attributeLabels() {
    return array(
        'user_id' => 'ID',
        'username' => 'Username',
        'email' => 'Email',
        'password' => 'Password',
        'salt' => 'Salt',
        'display_name' => 'Display Name',
        'activation_key' => 'Activation Key',
        'type' => 'Type',
        'status' => 'Status',
        'joined' => 'Joined',
        'first_name' => 'First Name',
        'last_name' => 'Last Name',
        'gender' => 'Gender',
        'social_provider' => 'Social Provider',
        'social_uid' => 'Social Uid',
        'access_token' => 'Access Token',
        'bio' => 'Bio',
        'last_login_time' => 'Last Login Time',
        'last_login_ip' => 'Last Login Ip',
        'country' => 'Country',
        'state' => 'State',
        'city' => 'City',
        'address' => 'Address',
        'phone' => 'Phone',
        'telephone' => 'Telephone',
        'mobile' => 'Mobile',
        'postcode' => 'Postcode',
        'featured' => 'Featured',
        'avatar' => 'Avatar',
        'webpage' => 'Webpage',
        'timezone' => 'Timezone',
        'language' => 'Language',
    );
  }

  /**
   * Retrieves a list of models based on the current search/filter conditions.
   * @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.
   */
  public function search() {
    // Warning: Please modify the following code to remove attributes that
    // should not be searched.

    $criteria = new CDbCriteria;

    $criteria->compare('user_id', $this->user_id);
    $criteria->compare('email', $this->email, true);
    $criteria->compare('display_name', $this->display_name, true);
    $criteria->compare('activation_key', $this->activation_key, true);
    $criteria->compare('type', $this->type, true);
    $criteria->compare('status', $this->status);
    $criteria->compare('joined', $this->joined);
    $criteria->compare('first_name', $this->first_name, true);
    $criteria->compare('last_name', $this->last_name, true);
    $criteria->compare('gender', $this->gender, true);
    $criteria->compare('social_provider', $this->social_provider, true);
    $criteria->compare('social_uid', $this->social_uid, true);
    $criteria->compare('bio', $this->bio, true);
    $criteria->compare('country', $this->country, true);
    $criteria->compare('state', $this->state, true);
    $criteria->compare('city', $this->city, true);
    $criteria->compare('address', $this->address, true);
    $criteria->compare('phone', $this->phone, true);
    $criteria->compare('telephone', $this->telephone, true);
    $criteria->compare('mobile', $this->mobile, true);
    $criteria->compare('postcode', $this->postcode, true);
    $criteria->compare('featured', $this->featured);
    $criteria->compare('webpage', $this->webpage, true);
    $criteria->compare('language', $this->language, true);

    //order
    $criteria->order = 'joined DESC';

    return new CActiveDataProvider($this, array(
        'criteria' => $criteria,
        'pagination' => array(
            'pageSize' => param('pageSize')
        )
    ));
  }

  /**
   * before save check is new user then update user register date
   * @return boolean
   */
  public function beforeSave() {
    if (parent::beforeSave()) {
      if ($this->isNewRecord) {
        $this->registered = time();

        //check
        if ($this->scenario == 'insert') {
          //create random salt
          $this->salt = $this->__generateSalt();
        }
      } else {
        
      }

      // in this case, we will use the old hashed password.
      if (empty($this->password) && empty($this->repassword) && !empty($this->initialPassword))
        $this->password = $this->repassword = $this->initialPassword;
      else
        $this->password = $this->hashPassword($this->password, $this->user_salt);

      return TRUE;
    }
    return FALSE;
  }

  /**
   * action after find result
   */
  public function afterFind() {
    //reset the password to null because we don't want the hash to be shown.
    $this->initialPassword = $this->password;
    $this->password = null;

    parent::afterFind();
  }

  /**
   * Checks if the given password is correct.
   * @param string the password to be validated
   * @return boolean whether the password is valid
   */
  public function validatePassword($password) {
    return $this->hashPassword($password, $this->salt) === $this->initialPassword;
  }

  /**
   * Generates the password hash.
   * @param string password
   * @param string salt
   * @return string hash
   */
  public function hashPassword($password, $salt) {
    return md5($salt . $password);
  }

  /**
   * Generates a salt that can be used to generate a password hash.
   * @return string the salt
   */
  protected function __generateSalt() {
    return uniqid('', true);
  }

  /**
   * get text of status
   * @return string
   */
  public function getStatusText() {
    switch ($this->status) {
      case self::STATUS_ACTIVE :
        $return = 'Actived';
        break;
      case self::STATUS_SUSPENDED :
        $return = 'Suspended';
        break;
      case self::STATUS_WAITING_ACTIVE :
        $return = 'Waiting to active';
        break;
      default :
        $return = 'Undefined';
        break;
    }

    return $return;
  }

  /**
   * get range status allow
   * @return array $status_key => $text
   */
  public static function getStatusRange() {
    return array(
        self::STATUS_WAITING_ACTIVE => 'Waiting Active',
        self::STATUS_ACTIVE => 'Active',
        self::STATUS_SUSPENDED => 'Suspended'
    );
  }

  /**
   * get type of current user
   */
  public function getType() {
    
  }

  /**
   * get avatar url of current user
   * allow size: small, thumb, medium, large, full
   * if user is logon with social provider, return url of social provider
   * @param string $size small, thumbnail, medium, large, full
   */
  public function getAvatarUrl($size = 'thumb') {
    switch ($size) {
      case 'thumb' :
        $width = 200;
        $height = 150;
        break;
      case 'small' :
        $width = 64;
        $height = 64;
        break;
      default :
        $width = 800;
        $height = 600;
        break;
    }

    if ($this->avatar == '' && $this->social_provider == '') {
      //empty
      $avatar = 'default.png';
    } else {
      $avatar = $this->avatar;
    }

    return ImageHelper::thumb($width, $height, 'avatar' . DIRECTORY_SEPARATOR . $avatar);
  }

  /**
   * get range of gender
   * @return array key => value
   */
  public static function getGenderRange() {
    return array(
        self::GENDER_FEMALE => 'Female',
        self::GENDER_MALE => 'Male'
    );
  }

  /**
   *
   * @return type
   */
  public static function getTypeRange() {
    return array(
        self::TYPE_MEMBER => 'Member',
        self::TYPE_ADMIN => 'Admin',
        self::TYPE_SUPER_ADMIN => 'Super Admin'
    );
  }

  public function getUser() {
    $user = Yii::app()->db->createCommand()
            ->select('*')
            ->from('{{users}} u')
            ->join('{{profiles}} p', 'u.user_id=p.user_id')
            ->queryAll();
    return $user;
  }

  /*
   * Get User For Home Page to like
   */
  public function getUserToViewed($offset, $sex) {
    $user = Yii::app()->db->createCommand()
            ->select('pf.*, up.link_img')
            ->from('profiles pf')
            ->leftjoin('user_photos up', 'up.approve = 1 and up.make_primary = 1 and up.user_id = pf.user_id')
            ->leftjoin('users u', 'u.user_id = pf.user_id')
            ->where('pf.gender=:sex and pf.user_id!=:user_id', array(':sex' => $sex,':user_id'=>user()->getUserProperty('user_id')))
            ->limit(1, $offset)
            ->queryRow();
    return $user;
  }

  /*
   * Get User For Home Page to like
   */
  public function getUserToViewedNoLimit() {
    $user = Yii::app()->db->createCommand()
            ->select('pf.*, up.link_img,u.username,u.email,u.created_at, u.last_login_time, u.last_login_ip,u.is_online')
            ->from('users u')
            ->leftjoin('user_photos up', 'up.approve = 1 and up.make_primary = 1 and up.user_id = u.user_id')
            ->leftjoin('profiles pf', 'pf.user_id = u.user_id')
            ->where('u.user_id!=:user_id and pf.user_id is not null', array(':user_id'=>user()->getUserProperty('user_id')))
            ->queryAll();
    
    return $user;
  }
  
  public function saveLastLogin($user_id){
    $command = Yii::app()->db->createCommand();
    $command->update('users', array(
        'last_login_time'=>date('Y-m-d H:i:s'),
        'last_login_ip'=>r()->userHostAddress
    ), 'user_id=:user_id', array(':user_id'=>$user_id));
  }
  
  public function deleteUserId($user_id){
    $command = Yii::app()->db->createCommand();
    $command->delete('profiles', 'user_id=:user_id', array(':user_id'=>$user_id));
    User::model()->deleteByPk($user_id);
  }

}